<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>JSDoc: Source: packages/select/src/select.vue</title>

    <script src="scripts/prettify/prettify.js"> </script>
    <script src="scripts/prettify/lang-css.js"> </script>
    <!--[if lt IE 9]>
      <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
    <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>

<body>

<div id="main">

    <h1 class="page-title">Source: packages/select/src/select.vue</h1>

    



    
    <section>
        <article>
            <pre class="prettyprint source linenums"><code>&lt;template>
  &lt;!-- 选择组件 -->
  &lt;div :class="`xdh-go__select ${customClass}`" :style="customStyle">
    &lt;slot name="tips" :alertTips="alertTips" :showTips="showTips">
      &lt;el-alert
        :title="`${alertTips}`"
        v-if="showTips"
        v-show="['rect', 'multi'].includes(selectMode)"
        :closable="false"
        type="warning"
        class="xdh-go__tips"
      >&lt;/el-alert>
    &lt;/slot>
    &lt;slot :menus="menus" :menuClick="menuClick">
      &lt;div class="xdh-go__menu">
        &lt;div
          v-for="(item, idx) in menus"
          :key="idx"
          :class="{'xdh-go__box': true, disabled: item.disabled || disabledAll}"
        >
          &lt;div v-if="!item.subMenu" @click="menuClick(item.name)">
            &lt;div class="icon-con">
              &lt;i :class="item.icon">&lt;/i>
            &lt;/div>
            &lt;div class="box">{{item.name}}&lt;/div>
          &lt;/div>
          &lt;div v-if="item.subMenu">
            &lt;div class="icon-con">
              &lt;i :class="item.icon">&lt;/i>
            &lt;/div>
            &lt;el-dropdown @command="(name) => menuClick(name)" trigger="click" class="submenu">
              &lt;span :class="{'el-dropdwon-link': true, 'disabled':item.disabled || disabledAll}">
                {{item.name}}
                &lt;i class="iconfont icon-bold-arrow-down" style="margin-left: 5px;">&lt;/i>
              &lt;/span>
              &lt;el-dropdown-menu slot="dropdown" class="xdh-go__dropdown">
                &lt;el-dropdown-item
                  :class="{active: item1.name === itemMap[selectMode]}"
                  :key="idx"
                  v-for="(item1, idx) in item.subMenu"
                  :command="item1.name"
                  :disabled="item1.disabled"
                >
                  &lt;el-popover
                    ref="popover"
                    placement="right"
                    :trigger="'hover'"
                    :content="item1.tips"
                    class="xdh-go__dropitem"
                  >
                    &lt;div slot="reference">{{item1.name}}&lt;/div>
                  &lt;/el-popover>
                &lt;/el-dropdown-item>
              &lt;/el-dropdown-menu>
            &lt;/el-dropdown>
          &lt;/div>
        &lt;/div>
      &lt;/div>
    &lt;/slot>
  &lt;/div>
&lt;/template>
&lt;script>
/**
 * XdhGoSelect 组件
 * @module xdh-go-select
 * @description 选择组件
 */
/**
 * 插槽
 * @member slots
 * @property {String} [default] 菜单选项插槽,slot-scope =
 * @property {Function} [default.menu] 菜单数组
 *                                     [
  {
    name: '选择',
    icon: 'iconfont icon-indicator',
    subMenu: [
      { name: '框选', tips: '点击框选或长按鼠标拖动可框选' },
      { name: '多选', tips: '点击多选或按住ctrl可多选' },
      {
        name: '全选',
        tips: '全选节点'
      },
      { name: '反选', tips: '反选节点' },
      { name: '选中子节点', tips: '选中指定节点的子节点' }
    ]
  }
]
 * @property {String} [default.menuClick] 菜单点击方法
 */
/**
 * 插槽
 * @member slots
 * @property {String} [tips] 操作提示插槽,slot-scope =
 * @property {String} [tips.alertTips] 提示信息
 * @property {Boolean} [tips.showTips] 是否显示提示信息
 */

import go from 'gojs'
let viewMenus = [
  {
    name: '选择',
    icon: 'iconfont icon-indicator',
    subMenu: [
      { name: '框选', tips: '点击框选或长按鼠标拖动可框选' },
      { name: '多选', tips: '点击多选或按住ctrl可多选' },
      {
        name: '全选',
        tips: '全选节点'
      },
      { name: '反选', tips: '反选节点' },
      { name: '选中子节点', tips: '选中指定节点的子节点' }
    ]
  }
]
export default {
  name: 'XdhGoSelect',
  /**
   * 参数属性
   * @property {Object} [diagram=null] go.Diagram对象
   * @property {Boolean} [showTips=true] 是否显示顶部操作提示
   * @property {String} [customClass=''] 自定义容器类名
   * @property {Object} [customStyle={}] 自定义样式
   * @property {Object} [itemMap] 选项名称对应关系 {
          normal: '普通',
          rect: '框选',
          multi: '多选',
          all: '全选',
          reverse: '反选',
          child: '选中子节点'
        }
   * @property {Array} [menus] 菜单项，默认
   [
  {
    name: '选择',
    icon: 'iconfont icon-indicator',
    subMenu: [
      { name: '框选', tips: '点击框选或长按鼠标拖动可框选' },
      { name: '多选', tips: '点击多选或按住ctrl可多选' },
      {
        name: '全选',
        tips: '全选节点'
      },
      { name: '反选', tips: '反选节点' },
      { name: '选中子节点', tips: '选中指定节点的子节点' }
    ]
  }
]
   */
  props: {
    diagram: {
      type: Object,
      default() {
        return null
      }
    },
    showTips: {
      type: Boolean,
      default: true
    },
    customClass: {
      type: String,
      default: ''
    },
    customStyle: {
      type: Object,
      default() {
        return {}
      }
    },
    itemMap: {
      type: Object,
      default() {
        return {
          normal: '普通',
          rect: '框选',
          multi: '多选',
          all: '全选',
          reverse: '反选',
          child: '选中子节点'
        }
      }
    },
    menus: {
      type: Array,
      default() {
        return viewMenus.filter(r => {
          return r.visible !== false
        })
      }
    }
  },
  watch: {
    diagram: {
      handler(diagram) {
        if (diagram) {
          this.unbindDiagramEvent()
          setTimeout(() => {
            this.bindDiagramEvent(diagram, go.GraphObject.make, go)
          }, 300)
        }
      }
    }
  },
  data() {
    return {
      itemReverseMap: {},
      disabledAll: false,
      selectMode: 'normal'
    }
  },
  computed: {
    alertTips() {
      if (this.selectMode === 'rect') {
        return '开始框选，按住ctrl可框选多处，点击esc退出'
      } else if (this.selectMode === 'multi') {
        return '开始多选，点击esc退出'
      } else {
        return '切换到普通模式'
      }
    }
  },
  methods: {
    keyupHandler(e) {
      e.preventDefault()
      switch (e.key) {
        case 'Escape':
          this.resetMode()
          break
      }
    },
    resetMode() {
      this.setSelectMode('normal')
    },
    toggleDisabledAll(disabled = true) {
      this.disabledAll = disabled
    },
    setSelectMode(mode) {
      let diagram = this.diagram
      let model = diagram.model
      model.setDataProperty(model.modelData, 'selectMode', mode)
      this.selectMode = mode
      diagram.clearHighlighteds()
      if (mode === 'rect') {
        diagram.toolManager.dragSelectingTool.delay = 0
      } else if (mode === 'all') {
        diagram.commandHandler.selectAll()
      } else if (mode === 'reverse') {
        diagram.nodes.each(N => {
          N.isSelected = !N.isSelected
        })
      } else if (mode === 'child') {
        let selections = this.getSelections(true)
        let set = new go.Set()
        selections.each(N => {
          set.add(N)
        })
        diagram.clearSelection()
        set.each(N => {
          this.selectChildren(N)
        })
      } else if (mode === 'multi') {
        diagram.clearSelection()
      } else if (mode === 'normal') {
        this.diagram.toolManager.dragSelectingTool.delay = 200
      }
        /**
       * 选择模式切换时触发
       * @event on-change
       * @param {String} mode 选择模式
       */
      this.$emit('on-change', mode)
    },
    getSelections(isObject = true) {
      if (isObject) {
        return this.diagram.selection
      } else {
        let res = []
        this.diagram.selection.each(node => {
          res.push(node.data)
        })
        return res
      }
    },
    selectChildren(node) {
      let children = node.findTreeChildrenNodes()
      if (children) {
        children.each(N => {
          N.isSelected = true
        })
      }
    },
    menuClick(name) {
      this.$emit('item-click', name)
      let tag = this.itemReverseMap[name]
      switch (tag) {
        // 选择功能
        case 'rect':
          this.setSelectMode('rect')
          break
        case 'multi':
          this.setSelectMode('multi')
          break
        case 'all':
          this.setSelectMode('all')
          break
        case 'reverse':
          this.setSelectMode('reverse')
          break
        case 'child':
          this.setSelectMode('child')
          break
      }
    },
    bindDiagramEvent(diagram, $, go) {
      this.diagram.addDiagramListener(
        'BackgroundSingleClicked',
        this.backgroundClick
      )
      diagram.addDiagramListener('ObjectSingleClicked', this.nodeClickSelect)
      // 框选按esc后默认会取消所有已选项，禁用
      diagram.commandHandler.doKeyDown = () => {
        let e = diagram.lastInput
        let cmd = diagram.commandHandler
        if (e.key !== 'Esc') {
          go.CommandHandler.prototype.doKeyDown.call(cmd)
        }
      }
      // 点击节点默认会只选当前节点，而取消之前选择的节点。多选状态下须取消此行为
      diagram.toolManager.clickSelectingTool.doMouseUp = () => {
        let e = diagram.lastInput
        let cmd = diagram.toolManager.clickSelectingTool
        if (['multi'].includes(this.selectMode)) {
          if (e.button === 0) {
            let node = diagram.findObjectAt(
              e.documentPoint,
              x => x.part,
              x => x.canSelect()
            )
            if (node) {
              node.isSelected = true
            } else {
              diagram.clearSelection()
              this.resetMode()
            }
            diagram.clearHighlighteds()
          }
        } else {
          go.ClickSelectingTool.prototype.doMouseUp.call(cmd)
        }
      }
      // 框选状态下禁用拖拽
      diagram.toolManager.draggingTool.doMouseMove = () => {
        let cmd = diagram.toolManager.draggingTool
        go.DraggingTool.prototype.doMouseMove.call(cmd)
        diagram.layout.invalidateLayout()
      }
    },
    nodeClickSelect(obj) {
      let node = obj.subject.part
      let isMultiSelect = false
      if (this.selectMode === 'multi') {
        this.diagram.clearHighlighteds()
        isMultiSelect = true
      }
      node.isSelected = true
      return isMultiSelect
    },
    backgroundClick() {
      this.resetMode()
      this.diagram.clearSelection()
    },
    unbindDiagramEvent() {
      this.diagram.removeDiagramListener(
        'BackgroundSingleClicked',
        this.backgroundClick
      )
      this.diagram.removeDiagramListener(
        'ObjectSingleClicked',
        this.nodeClickSelect
      )
      this.diagram.toolManager.draggingTool.doMouseMove =
        go.DraggingTool.prototype.doMouseMove
      this.diagram.toolManager.clickSelectingTool.doMouseUp =
        go.ClickSelectingTool.prototype.doMouseUp
      this.diagram.commandHandler.doKeyDown =
        go.CommandHandler.prototype.doKeyDown
    }
  },
  mounted() {
    if (this.diagram) {
      this.bindDiagramEvent(this.diagram, go.GraphObject.make, go)
    }
    window.addEventListener('keyup', this.keyupHandler)
  },
  created() {
    let itemReverse = {}
    Object.entries(this.itemMap).forEach(r => {
      itemReverse[r[1]] = r[0]
    })
    this.itemReverseMap = itemReverse
  },
  beforeDestroy() {
    window.removeEventListener('keyup', this.keyupHandler)
    this.unbindDiagramEvent()
  }
}
&lt;/script>
&lt;style type="text/scss" lang="scss" scoped>
&lt;/style></code></pre>
        </article>
    </section>




</div>

<nav>
    <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-utils_directives_draggable.html">utils/directives/draggable</a></li><li><a href="module-utils_directives_resizable.html">utils/directives/resizable</a></li><li><a href="module-utils_events.html">utils/events</a></li><li><a href="module-utils_storage.html">utils/storage</a></li><li><a href="module-xdh-go.html">xdh-go</a></li><li><a href="module-xdh-go-circle-menu.html">xdh-go-circle-menu</a></li><li><a href="module-xdh-go-draft.html">xdh-go-draft</a></li><li><a href="module-xdh-go-html.html">xdh-go-html</a></li><li><a href="module-xdh-go-layout.html">xdh-go-layout</a></li><li><a href="module-xdh-go-overview.html">xdh-go-overview</a></li><li><a href="module-xdh-go-search.html">xdh-go-search</a></li><li><a href="module-xdh-go-select.html">xdh-go-select</a></li><li><a href="module-xdh-go-snapshot.html">xdh-go-snapshot</a></li><li><a href="module-xdh-go-tool.html">xdh-go-tool</a></li><li><a href="module-xdh-go-tooltiip.html">xdh-go-tooltiip</a></li><li><a href="module-xdh-go-view.html">xdh-go-view</a></li><li><a href="module-xdh-go-viewer.html">xdh-go-viewer</a></li></ul><h3>Classes</h3><ul><li><a href="module-utils_directives_draggable-Draggable.html">Draggable</a></li><li><a href="module-utils_directives_resizable-Resizable.html">Resizable</a></li><li><a href="module-utils_events-Events.html">Events</a></li></ul><h3>Events</h3><ul><li><a href="module-xdh-go-view.html#~event:item-click">item-click</a></li><li><a href="module-xdh-go-select.html#~event:on-change">on-change</a></li><li><a href="module-xdh-go-search.html#~event:on-error">on-error</a></li><li><a href="module-xdh-go-circle-menu.html#~event:on-item-click">on-item-click</a></li><li><a href="module-xdh-go.html#~event:on-load-data">on-load-data</a></li><li><a href="module-xdh-go.html#~event:on-ready">on-ready</a></li><li><a href="module-xdh-go-search.html#~event:on-search">on-search</a></li><li><a href="module-xdh-go-snapshot.html#~event:on-snap">on-snap</a></li></ul><h3>Global</h3><ul><li><a href="global.html#animationPool">animationPool</a></li><li><a href="global.html#bindToState">bindToState</a></li><li><a href="global.html#ease">ease</a></li><li><a href="global.html#easeInBack">easeInBack</a></li><li><a href="global.html#easeInBounce">easeInBounce</a></li><li><a href="global.html#easeInCirc">easeInCirc</a></li><li><a href="global.html#easeInCubic">easeInCubic</a></li><li><a href="global.html#easeInElastic">easeInElastic</a></li><li><a href="global.html#easeInExpo">easeInExpo</a></li><li><a href="global.html#easeInOutBack">easeInOutBack</a></li><li><a href="global.html#easeInOutBounce">easeInOutBounce</a></li><li><a href="global.html#easeInOutCubic">easeInOutCubic</a></li><li><a href="global.html#easeInOutQuad">easeInOutQuad</a></li><li><a href="global.html#easeInOutQuart">easeInOutQuart</a></li><li><a href="global.html#easeInOutQuint">easeInOutQuint</a></li><li><a href="global.html#easeInOutSine">easeInOutSine</a></li><li><a href="global.html#easeInQuad">easeInQuad</a></li><li><a href="global.html#easeInQuart">easeInQuart</a></li><li><a href="global.html#easeInQuint">easeInQuint</a></li><li><a href="global.html#easeInSine">easeInSine</a></li><li><a href="global.html#easeOutBack">easeOutBack</a></li><li><a href="global.html#easeOutBounce">easeOutBounce</a></li><li><a href="global.html#easeOutCirc">easeOutCirc</a></li><li><a href="global.html#easeOutCubic">easeOutCubic</a></li><li><a href="global.html#easeOutElastic">easeOutElastic</a></li><li><a href="global.html#easeOutExpo">easeOutExpo</a></li><li><a href="global.html#easeOutQuad">easeOutQuad</a></li><li><a href="global.html#easeOutQuart">easeOutQuart</a></li><li><a href="global.html#easeOutQuint">easeOutQuint</a></li><li><a href="global.html#easeOutSine">easeOutSine</a></li><li><a href="global.html#extendOption">extendOption</a></li><li><a href="global.html#genOption">genOption</a></li><li><a href="global.html#getHandler">getHandler</a></li><li><a href="global.html#handleEvents">handleEvents</a></li><li><a href="global.html#handleParts">handleParts</a></li><li><a href="global.html#horPanel%25E6%25B0%25B4%25E5%25B9%25B3%25E5%25B8%2583%25E5%25B1%2580">horPanel 水平布局</a></li><li><a href="global.html#makePort">makePort</a></li><li><a href="global.html#node%25E8%258A%2582%25E7%2582%25B9%25E5%25AE%259A%25E4%25B9%2589">node 节点定义</a></li><li><a href="global.html#removeGray">removeGray</a></li><li><a href="global.html#setGray">setGray</a></li><li><a href="global.html#shapeParamsBinding">shapeParamsBinding</a></li><li><a href="global.html#spotPanelspot%25E5%25B8%2583%25E5%25B1%2580">spotPanel spot布局</a></li><li><a href="global.html#verPanel%25E5%259E%2582%25E7%259B%25B4%25E5%25B8%2583%25E5%25B1%2580">verPanel 垂直布局</a></li></ul>
</nav>

<br class="clear">

<footer>
    Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 3.6.3</a> on Tue Nov 05 2019 16:15:35 GMT+0800 (GMT+08:00)
</footer>

<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>
